package com.chuangan.releasetask.service.impl;


import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.chuangan.releasetask.Utils.PayCommonUtil;
import com.chuangan.releasetask.Utils.WxUtils;
import com.chuangan.releasetask.config.AliPayAccountConfig;
import com.chuangan.releasetask.config.WechatAccountConfig;
import com.chuangan.releasetask.dto.WebDTO;
import com.chuangan.releasetask.mapper.UserMapper;
import com.chuangan.releasetask.service.PayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;


/**
 * @Author: zihua
 * @Date: 2020/6/5 16:58
 * @Version 1.0
 */
@Service
@Transactional
@Slf4j
public class PayServiceImpl implements PayService {



    @Autowired
    private WechatAccountConfig wechatAccountConfig;

    // 下单 API 地址
    private String placeUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";

    @Autowired
    private WxUtils wxUtils;



    @Autowired
    private UserMapper userMapper;

    /**
     * 功能描述: 支付宝支付
     * @Return:
     * @Author: jinLong
     * @Date: 2020/11/2 14:06
     */
    @Override
    public Map<String, Object> AliPay(WebDTO webDTO) {
        Map<String, Object> map = new HashMap<>();
        if (StringUtils.isEmpty(webDTO)) {
            map.put("code", 500);
            map.put("msg", "网络异常");
            return map;
        }
        String  noMember= userMapper.findOneUser(webDTO.getUserAccount()).getUserMember();
        if(noMember.equals("1")){
            map.put("code", 500);
            map.put("msg", "你已开通会员");
            return map;
        }else {
            /* 查询订单信息 */
            AlipayClient alipayClient = new DefaultAlipayClient(AliPayAccountConfig.url, AliPayAccountConfig.app_id, AliPayAccountConfig.private_key, AliPayAccountConfig.format, AliPayAccountConfig.charset, AliPayAccountConfig.public_key, AliPayAccountConfig.signtype);//支付宝需要的参数serverUrl、appId、private_key、format、charset、public_key、signType
            AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
            model.setBody("支付宝支付");//商品信息
            model.setSubject("开通会员");//商品名称
            model.setOutTradeNo(String.valueOf(UUID.randomUUID()));//订单号
            model.setTimeoutExpress("30m");//支付超时时间
            model.setPassbackParams(webDTO.getUserAccount());
            model.setTotalAmount(String.valueOf(0.01));// 支付金额
//        model.setTotalAmount(String.valueOf(webDTO.getMemberMoney()));// 支付金额
            request.setBizModel(model);
            // 回调地址(充值订单)
        request.setNotifyUrl(AliPayAccountConfig.notify_url);// 回调地址
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response = null;
            try {
                response = alipayClient.sdkExecute(request);
                map.put("code", 200);
                Map<String, Object> dataMap = new HashMap<>();
                dataMap.put("payPath", response.getBody());
                map.put("data", dataMap);
                return map;
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
        }
        map.put("code",500);
        map.put("msg", "支付失败!");
        return map;
    }






    /**
     *
     * 功能描述: 支付宝异步回调
     * @Return:
     * @Author: jinLong
     * @Date: 2020/11/2 14:43
     */
    @Override
    public String Alinotify(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> params = new HashMap<String, String>();
        //从支付宝回调的request域中取值
        Map<String, String[]> requestParams = request.getParameterMap();

        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }
        String userAccount = params.get("passback_params");

        // 当前交易状态
        String trade_status = params.get("trade_status");
            //验签通过
            if(trade_status.equals("TRADE_SUCCESS")) {
                //支付成功后的业务处理
                //这里开通会员，修改状态
                userMapper.updateuserMember(userAccount,"1");
                return "success";
            }

        return "failure";
    }




    @Transactional
    @Override
    public String callBack(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 预先设定返回的 response 类型为 xml
        response.setHeader("Content-type", "application/xml");
        // 读取参数，解析Xml为map
        Map<String, String> map = wxUtils.transferXmlToMap(wxUtils.readRequest(request));
        // 转换为有序 map，判断签名是否正确
        boolean isSignSuccess = wxUtils.checkSign(new TreeMap<String, Object>(map), PayCommonUtil.MCH_KEY);
        if (isSignSuccess) {
            System.out.println("支付成功");
            // 签名校验成功，说明是微信服务器发出的数据
//支付成功后的业务处理
            //这里开通会员，修改状态
//            userMapper.updateuserMember(userAccount,"1");
            return success();
        } else {
            // 签名校验失败（可能不是微信服务器发出的数据）
            return fail();
        }
    }


    String fail() {
        return "<xml>\n" +
                "  <return_code><![CDATA[FAIL]]></return_code>\n" +
                "  <return_msg><![CDATA[]]></return_msg>\n" +
                "</xml>";
    }

    String success() {
        return "<xml>\n" +
                "  <return_code><![CDATA[SUCCESS]]></return_code>\n" +
                "  <return_msg><![CDATA[OK]]></return_msg>\n" +
                "</xml>";
    }


}
